package com.tengju.bff.interfaces.covercharge.util;

import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


/**
 *@author liang_shi
 *@date 2020/7/13 14:43
 *@description 
 */
public class MySSLSocketFactory {

    /**
     * The Tm.
     */
    static X509TrustManager tm = null;
    /**
     * The Ctx.
     */
    static SSLContext ctx = null;
    /**
     * The Dhv.
     */
    static HostnameVerifier dhv = null;

    private static final Object SYNCLOCK = new Object();

    private MySSLSocketFactory() {
    }

    /**
     * Gets ssl Context.
     *
     * @return the ssl socket
     * @throws Exception the exception
     */
    public static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
        if (null != ctx) {
            return ctx;
        }
        synchronized (SYNCLOCK) {
            if (null == ctx) {
                //TLSv1, TLSv1.1, TLSv1.2
                ctx = SSLContext.getInstance("TLSv1.1");
                ctx.init(null, new TrustManager[]{getDefaultTrustManager()}, new java.security.SecureRandom());
            }
        }
        return ctx;
    }

    public static SSLContext getSSLContext(String tlsv) throws NoSuchAlgorithmException, KeyManagementException {
        if (null != ctx) {
            return ctx;
        }
        synchronized (SYNCLOCK) {
            if (null == ctx) {
                //TLSv1, TLSv1.1, TLSv1.2
                ctx = SSLContext.getInstance(tlsv);
                ctx.init(null, new TrustManager[]{getDefaultTrustManager()}, new java.security.SecureRandom());
            }
        }
        return ctx;
    }

    /**
     * 创建SSLContext对象，并使用我们指定的信任管理器初始化
     *
     * @return ssl socket factory
     * @throws Exception the exception
     */
    public static SSLSocketFactory getSSLSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        // 从上述SSLContext对象中得到SSLSocketFactory对象
        return getSSLContext().getSocketFactory();
    }

    /**
     * Gets default x 509 trust manager.
     *
     * @return the default x 509 trust manager
     */
    public static X509TrustManager getDefaultTrustManager() {
        if (null != tm) {
            return tm;
        }
        synchronized (SYNCLOCK) {
            if (tm == null) {
                tm = new DefaultTrustManager();
            }
        }
        return tm;
    }


    /**
     * Gets default hostname verifier.
     *
     * @return the default hostname verifier
     */
    public static HostnameVerifier getDefaultHostnameVerifier() {
        if (null != dhv) {
            return dhv;
        }
        synchronized (SYNCLOCK) {
            if (dhv == null) {
                dhv = new DefaultHostnameVerifier();
            }
        }
        return dhv;
    }

    /**
     *
     */
    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            //no check
        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            //no check
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    /**
     * URL为IP时，默认是通不过验证的，需要自己定义HostName的验证方法
     */
    private static class DefaultHostnameVerifier implements HostnameVerifier {
        private DefaultHostnameVerifier() {
        }

        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    }

}
